#include "pch.h"

#include "GlassShatterScreenMesh.h"
#include "Rendering/ConstantBuffers.h"
#include "DirectX/DirectXHelper.h"
#include "GameObjects/GameConstants.h"

using namespace DirectX;

GlassShatterScreenMesh::GlassShatterScreenMesh(_In_ ID3D11Device *device, _In_ ID3D11InputLayout* inputLayout) :
	MeshObject(inputLayout)
{
	D3D11_BUFFER_DESC bd = {0};
	D3D11_SUBRESOURCE_DATA initData = {0};

	// Octagon defined by the following points:
	// ( 2.0f, 10.0f, z), (17.0f, 10.0f, z), (19.0f,  8.0f, z), (19.0f,  2.0f, z),
	// (17.0f,  0.0f, z), ( 2.0f,  0.0f, z), ( 0.0f,  2.0f, z), ( 0.0f,  8.0f, z)
	// Need to construct my triangles within those points.
	// Start with 8 triangles, break each into two then each into two: result - 32 triangles. break along longest line.
	// Need new vertex type: position, normal, texture, triangleCenter, rotationalVelocity. Start with 8 triangles (24 vertices) and if that basically works then progress from there.
	// Ok to have them indexed. At the end just troll the indexes and push_back a copy of each vertex.
	std::array<PNTVertex, GameConstants::Particles::ParticleCount> vertices;
	float z = 0.0f;
	XMFLOAT3 normal = XMFLOAT3(0.0f, 0.0f, 1.0f);
	float randMax = static_cast<float>(RAND_MAX);

	PNTVertex v = {};
	v.normal = XMFLOAT3(0.0f, 0.0f, 1.0f);

	const float offset = 64.0f / 512.0f;
	for (uint32 i = 0; i < GameConstants::Particles::ParticleCount; ++i)
	{
		v.position = XMFLOAT3(
			(rand() / randMax) * 17 + 1,
			(rand() / randMax) * 8 + 1, 
			(rand() / randMax) * -GameConstants::Particles::MaxStartingDepth
			);
		int texNum = rand() % GameConstants::Particles::SubTextureCount;
		int y = 0;
		while (texNum > 7)
		{
			texNum -= 8;
			++y;
		}
		v.textureCoordinate = XMFLOAT2(texNum * offset, y * offset);	
		vertices[i] = v;
	}

	m_vertexCount = static_cast<int>(vertices.size());
	m_stride = sizeof(PNTVertex);

	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = static_cast<UINT>(sizeof(vertices.front()) * vertices.size());
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	initData.pSysMem = &(vertices.front());
	DX::ThrowIfFailed(
		device->CreateBuffer(&bd, &initData, &m_vertexBuffer)
		);
}

void GlassShatterScreenMesh::Render(_In_ ID3D11DeviceContext* context, bool /*isFirstPass*/)
{
	// Note: We intentionally do not call the base class Render here.

	uint32 offset = 0;

	context->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &m_stride, &offset);
	context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
	context->IASetInputLayout(m_inputLayout.Get());

	context->Draw(GameConstants::Particles::ParticleCount, 0);
}